#ifndef ServerIoService_H
#define ServerIoService_H

#include <QtCore>

#include <boost/process.hpp>
#include <boost/asio.hpp>

#include <list>
#include <mutex>

namespace simodo::edit::plugin::model_server
{

class ServerIoService : public QObject
{
public:
    ServerIoService() = delete;
    ServerIoService(boost::asio::io_service & io
                  , std::string process_path
                  , std::vector<std::string> process_args);
    virtual ~ServerIoService() override;

    // @throws std::logic_error если сервер не найден
    void write(std::string message);
    void stop();

signals:
    void recieved(QVariant message);

private:
    Q_OBJECT

    boost::asio::io_service &       _io;
    std::string                     _process_path;
    std::vector<std::string>        _process_args;

    /*
        Группа нужна затем, чтобы при
        прерывании процесса он
        не становился зомби
    */
    std::shared_ptr<boost::process::async_pipe> _server_input;
    std::shared_ptr<boost::process::async_pipe> _server_output;
    std::shared_ptr<boost::process::group> _group;
    std::shared_ptr<boost::process::child> _server;

    std::list<std::string> _server_input_buffers;

    std::vector<char> _server_output_buffer;

    std::mutex _m;

    void _launchServer();
    void _stop();
    void _asyncRead(const boost::system::error_code & ec, size_t size);
    void _postAsyncRead();
};

}

#endif // ServerIoService_H
